home *** CD-ROM | disk | FTP | other *** search
- reversing a lame cd-check, pay attention boy! by R!SC -- risc@notme.com
-
-
- starting from the top, cd-checks normally use kernel32!getdrivetypea to find out what sort of
- drive they are looking at, you simply push a pointer to a drive letter, then after getdrivetypea
- eax=03 for hard disk or eax=05 for a cd-rom.
-
- so load crackcd.exe, enter softice, and type in 'bpx getdrivetypea'. Click on the CheckCD
- button, and bingo! we have located the code to check the CD.. now pay close attention to the
- comments in dead listing...
-
-
-
- 015F:004011B3 68EB234000 PUSH 004023EB ; pointer to 'kernel32.dll',0
- 015F:004011B8 E861070000 CALL KERNEL32!LoadLibraryA
- 015F:004011BD 8BF0 MOV ESI,EAX ; save address of kernel32 in esi
- 015F:004011BF 8D85E8FBFFFF LEA EAX,[EBP+FFFFFBE8]
- 015F:004011C5 50 PUSH EAX ; pointer to some free space
- 015F:004011C6 68F8234000 PUSH 004023F8 ; pointer to getdrivetypea (wide char...)
- 015F:004011CB E8C3020000 CALL 00401493 ; convert it to normal, pasting it into the free space
- 015F:004011D0 83C408 ADD ESP,08
- 015F:004011D3 8D95E8FBFFFF LEA EDX,[EBP+FFFFFBE8]
- 015F:004011D9 52 PUSH EDX ; points to the converted 'getdrivetypea'
- 015F:004011DA 56 PUSH ESI ; kernel32
- 015F:004011DB E820070000 CALL KERNEL32!GetProcAddress ; returns the address of 'getdrivetypea' in eax
- 015F:004011E0 6A00 PUSH 00 ; null, return the drivetype of the current drive
- 015F:004011E2 FFD0 CALL EAX ; call getdrivetypea (where softice will break)
- 015F:004011E4 8BF8 MOV EDI,EAX ; eax will == 3 if the program is run from harddisk
- 015F:004011E6 56 PUSH ESI
- 015F:004011E7 E820070000 CALL KERNEL32!FreeLibrary ; free the kernel :) he didnt do it..
- 015F:004011EC 682C010000 PUSH 0000012C ; size of buffer to store windows directory
- 015F:004011F1 8D85BCFAFFFF LEA EAX,[EBP+FFFFFABC]
- 015F:004011F7 50 PUSH EAX ; pointer to buffer
- 015F:004011F8 E8EB060000 CALL KERNEL32!GetWindowsDirectoryA
- 015F:004011FD 6880000000 PUSH 00000080 ; size of buffer for modulefilename
- 015F:00401202 8D95E8FBFFFF LEA EDX,[EBP+FFFFFBE8]
- 015F:00401208 52 PUSH EDX ; pointer to buffer
- 015F:00401209 FF35B0254000 PUSH DWORD PTR [004025B0] ; 00400000, this module...
- 015F:0040120F E8DA060000 CALL KERNEL32!GetModuleFileNameA
- 015F:00401214 8A8DBCFAFFFF MOV CL,[EBP+FFFFFABC] ; [c:\windows] ;WindowsDirectoryA
- 015F:0040121A 3A8DE8FBFFFF CMP CL,[EBP+FFFFFBE8] ; [c:\checkcd1\checkcd.exe] ;ModuleFileNameA
- 015F:00401220 7518 JNZ 0040123A ; check the drive letters...jump if not equal
-
- yah, all the above code does is get the windows path/directory, get its own path/directory,
- compare the drive letters, so it cant be run from the same drive that windows is installed on.
- it also get's the drivetype of the current drive, and stores this in EDI...
-
- 015F:00401220 7518 JNZ 0040123A ; has to be taken, so change it to a JMP
- eb18
-
- on with the reversing...
-
- 015F:00401222 6A00 PUSH 00
- 015F:00401224 6A00 PUSH 00
- 015F:00401226 8D45B0 LEA EAX,[EBP-50]
- 015F:00401229 50 PUSH EAX ; pointer to wide char 'HeHe! Try again'
- 015F:0040122A 53 PUSH EBX
- 015F:0040122B E81C020000 CALL 0040144C ; convert wide char, display messagebox
- 015F:00401230 83C410 ADD ESP,10
- 015F:00401233 33C0 XOR EAX,EAX
- 015F:00401235 E909020000 JMP 00401443 ; jump to exit (failed cd-check)
-
- 015F:0040123A 83EF05 SUB EDI,05 ; where we end up if we take the first good-check jump
- 015F:0040123D 0F8596010000 JNZ 004013D9 ; 05=cd-rom, 05-05=0, so edi must be 0 to carry on.
- 015F:00401243 8D9574FCFFFF LEA EDX,[EBP-038C] ; total number of clusters
- 015F:00401249 52 PUSH EDX ; pointers
- 015F:0040124A 8D8D78FCFFFF LEA ECX,[EBP-0388] ; how many free clusters
- 015F:00401250 51 PUSH ECX ; to
- 015F:00401251 8D857CFCFFFF LEA EAX,[EBP-0384] ; bytes per sector
- 015F:00401257 50 PUSH EAX ; various
- 015F:00401258 8D9580FCFFFF LEA EDX,[EBP-0380] ; sectors per cluster
- 015F:0040125E 52 PUSH EDX ; buffers
- 015F:0040125F 6A00 PUSH 00 ; pRootPathName, null = current drive
- 015F:00401261 E8BE060000 CALL KERNEL32!GetDiskFreeSpaceA
- 015F:00401266 83BD78FCFFFF00 CMP DWORD PTR [EBP-0388],00 ; compare the amount of free clusters with '0'
- 015F:0040126D 7418 JZ 00401287 ; again, if it was run from CD, the freespace is always '0'
-
- okay, still simple enough, subtracts 5 from the returned value for this drive, if its not equal,
- i.e. not zero, jumps to the 'hehe try again' messagebox, if it passed this part, it checks for
- free space, and there should be none on a CD, so ...
-
- 015F:0040123D 0F8596010000 JNZ 004013D9 ; this jump has to be killed to carry on with the check
- 0f8500000000
-
- 015F:0040126D 7418 JZ 00401287 ; this jump has to be taken to carry on...
- eb18
-
- on with the reversing...
-
- 015F:0040126F 6A00 PUSH 00
- 015F:00401271 6A00 PUSH 00
- 015F:00401273 8D4DB0 LEA ECX,[EBP-50] ; de-ja-vu
- 015F:00401276 51 PUSH ECX ; pointer to wide char 'HeHe! Try again'
- 015F:00401277 53 PUSH EBX
- 015F:00401278 E8CF010000 CALL 0040144C ; our message box friend again
- 015F:0040127D 83C410 ADD ESP,10
- 015F:00401280 33C0 XOR EAX,EAX
- 015F:00401282 E9BC010000 JMP 00401443 ; jump to exit (failed cd-check)
-
- 015F:00401287 6880000000 PUSH 00000080
- 015F:0040128C 8D95BCF9FFFF LEA EDX,[EBP+FFFFF9BC]
- 015F:00401292 52 PUSH EDX
- 015F:00401293 8D8D68FCFFFF LEA ECX,[EBP-0398]
- 015F:00401299 51 PUSH ECX
- 015F:0040129A 8D856CFCFFFF LEA EAX,[EBP-0394]
- 015F:004012A0 50 PUSH EAX
- 015F:004012A1 8D9570FCFFFF LEA EDX,[EBP-0390]
- 015F:004012A7 52 PUSH EDX
- 015F:004012A8 6880000000 PUSH 00000080
- 015F:004012AD 8D8D3CFAFFFF LEA ECX,[EBP+FFFFFA3C]
- 015F:004012B3 51 PUSH ECX
- 015F:004012B4 6A00 PUSH 00
- 015F:004012B6 E839060000 CALL KERNEL32!GetVolumeInformationA
- 015F:004012BB 81BD70FCFFFF21787573CMP DWORD PTR [EBP-0390],73757821 ; compare read label with 'sux!'
- 015F:004012C5 0F85F9000000 JNZ 004013C4 ; jump if not equal to failed check...
- 015F:004012CB F68568FCFFFF10 TEST BYTE PTR [EBP-0398],10 ; i dont know, but it has to be equal :)
- 015F:004012D2 7418 JZ 004012EC ; jump passed horrid message if above test is true
- 015F:004012D4 6A00 PUSH 00
- 015F:004012D6 6A00 PUSH 00
- 015F:004012D8 8D45B0 LEA EAX,[EBP-50] ;de-ja-vu again
- 015F:004012DB 50 PUSH EAX ; see the pattern, ebp-50, call 40144c?
- 015F:004012DC 53 PUSH EBX
- 015F:004012DD E86A010000 CALL 0040144C
- 015F:004012E2 83C410 ADD ESP,10
- 015F:004012E5 33C0 XOR EAX,EAX
- 015F:004012E7 E957010000 JMP 00401443
-
- 015F:004012EC F68569FCFFFF80 TEST BYTE PTR [EBP-0397],80 ; i dont know, but it has to be equal :)
- 015F:004012F3 7418 JZ 0040130D ; jump passed horrid message if above test is true
- 015F:004012F5 6A00 PUSH 00
- 015F:004012F7 6A00 PUSH 00
- 015F:004012F9 8D55B0 LEA EDX,[EBP-50] ; we know this is the bad cracker bit
- 015F:004012FC 52 PUSH EDX ; so we take the above jump...
- 015F:004012FD 53 PUSH EBX
- 015F:004012FE E849010000 CALL 0040144C
- 015F:00401303 83C410 ADD ESP,10
- 015F:00401306 33C0 XOR EAX,EAX
- 015F:00401308 E936010000 JMP 00401443
-
- right, i have been a very naughty boy, and admit that two parts of this code i dont understand,
- but from the bad-cracker code being duped everywhere, i know to take the jumps.. basicaly, this
- is a label check, chacks the disk label against 'sux!', and if they are the same, does these
- other two tests, which have to pass to skip the 'hehe! try again' message..
-
- 015F:004012C5 0F85F9000000 JNZ 004013C4 ; label check, we want to skip this jump...
- 0f8500000000
-
- 015F:004012D2 7418 JZ 004012EC ; dont know, but it needs taking (JMP)
- eb18
-
- 015F:004012F3 7418 JZ 0040130D ; still dont know, but take it (JMP)
- eb18
-
- on with the reversing...
-
- 015F:0040130D 6814244000 PUSH 00402414 ; some bullshit 'stack overflow'
- 015F:00401312 8D953CFAFFFF LEA EDX,[EBP+FFFFFA3C] ;[ebp+fffffa3c] is from getvolumeinformationa routine
- 015F:00401318 52 PUSH EDX ; some more bullshit 'OVERFLOW'
- 015F:00401319 E888050000 CALL 004018A6 ; dont care :(
- 015F:0040131E 83C408 ADD ESP,08
- 015F:00401321 85C0 TEST EAX,EAX ; fuckit, change this to xor eax,eax
- 015F:00401323 0F8586000000 JNZ 004013AF ; so this jump wont be taken cause at 4013af, is the bad check code
- 015F:00401329 681A244000 PUSH 0040241A ; pointer to a new label
- 015F:0040132E 6A00 PUSH 00 ; what drive to change
- 015F:00401330 E8DD050000 CALL KERNEL32!SetVolumeLabelA
- 015F:00401335 48 DEC EAX ; eax = 1 if function succeed
- 015F:00401336 7526 JNZ 0040135E ; you cant change a CD's label, so eax should be 0 or -1
- ; but after the dec eax, if it failed, this jump would be taken..
-
- 015F:00401338 8D8D3CFAFFFF LEA ECX,[EBP+FFFFFA3C] ; waste
- 015F:0040133E 51 PUSH ECX ; of
- 015F:0040133F 6A00 PUSH 00 ; time
- 015F:00401341 E8CC050000 CALL KERNEL32!SetVolumeLabelA
- 015F:00401346 6A00 PUSH 00
- 015F:00401348 6A00 PUSH 00
- 015F:0040134A 8D45B0 LEA EAX,[EBP-50] ; bad cracker routine
- 015F:0040134D 50 PUSH EAX
- 015F:0040134E 53 PUSH EBX
- 015F:0040134F E8F8000000 CALL 0040144C ; again :)
- 015F:00401354 83C410 ADD ESP,10
- 015F:00401357 33C0 XOR EAX,EAX
- 015F:00401359 E9E5000000 JMP 00401443
-
- 015F:0040135E 6A00 PUSH 00
- 015F:00401360 8D55A8 LEA EDX,[EBP-58]
- 015F:00401363 52 PUSH EDX ;pointer to a filename
- 015F:00401364 E891050000 CALL KERNEL32!_lcreat ;try to create a file
- 015F:00401369 83F8FF CMP EAX,-01 ; would fail, if it tried to create a file on a CD
- 015F:0040136C 7428 JZ 00401396 ; as they are read-only, so force this jump...
-
- 015F:0040136E 50 PUSH EAX
- 015F:0040136F E892050000 CALL KERNEL32!_lclose ; whoops, we succeeded, so close the newly created file-handle
- 015F:00401374 8D4DA8 LEA ECX,[EBP-58]
- 015F:00401377 51 PUSH ECX
- 015F:00401378 E835050000 CALL 004018B2
- 015F:0040137D 59 POP ECX
- 015F:0040137E 6A00 PUSH 00
- 015F:00401380 6A00 PUSH 00
- 015F:00401382 8D45B0 LEA EAX,[EBP-50] ;DEJAVU again :0
- 015F:00401385 50 PUSH EAX
- 015F:00401386 53 PUSH EBX
- 015F:00401387 E8C0000000 CALL 0040144C ; messagebox
- 015F:0040138C 83C410 ADD ESP,10
- 015F:0040138F 33C0 XOR EAX,EAX
- 015F:00401391 E9AD000000 JMP 00401443
-
- 015F:00401396 6A00 PUSH 00 ; if we couldnt create the file, we end up here
- 015F:00401398 6823244000 PUSH 00402423 ; pointer to 'y.e.p.'
- 015F:0040139D 8D55D4 LEA EDX,[EBP-2C]
- 015F:004013A0 52 PUSH EDX ; pointer to 'y.a.y.!. .y.o.u. .c.r.a.c.k.e.d. .i.t.!.'
- 015F:004013A1 53 PUSH EBX
- 015F:004013A2 E8A5000000 CALL 0040144C ; messagebox...
- 015F:004013A7 83C410 ADD ESP,10
- 015F:004013AA E992000000 JMP 00401441
-
- hmm, the bit at the start, stack overflow, dont understand what or why, but kill this jump
-
- 015F:00401323 0F8586000000 JNZ 004013AF
- 0f8500000000
-
- you cant change the label of a CD, so this jump needs forcing
-
- 015F:00401336 7526 JNZ 0040135E
- eb26
-
- last but not least, you cant create a file on a CD, so this jump needs forcing aswell..
-
- 015F:0040136C 7428 JZ 00401396
- eb28
-
- wayhey, then we finally reach the good boy message box!! yippee!!!
-
- after studying the code, and realising what has been done, it just does some simple checks,
- then compares the return codes against what they should be, we dont want it re-labeling our
- hard disk drive to 'overflow', or creating a file called 'my.dog', basically, we can skip the
- whole routine, and just end up at the goodboy message box..so bpx at the first instruction
-
- 015F:004011B3 68EB234000 PUSH 004023EB ; pointer to 'kernel32.dll',0
-
- and re-assemble it to jump to the good-boy message box..
-
- a 4011b3 <ret>
- jmp 401396 <ret>
- <esc>
- x <ret>
-
- 015F:004011B3 E9DE010000 JMP 00401396 ; skip whole of check, go straight to jail
- ; do not pass go, do not collect 200..
- :)
-
- then you have a almost cracked checkcd.exe... just gotta patch it, but i cant be bothered, so
- i used my process patcher to create a loader for it..(availble from http://csir.xxx.xxx :)
-
- no plugz.. :)
-
- happy reversing / cracking / whatever..
-
- R!SC 6/6/99
-
-
-
-